/************************************************************************************
*                                                                                   *
*   MDX2DAE - MDX to COLLADA converter                                              *
*   Copyright (C) 2010  Gunnar Lilleaasen                                           *
*                                                                                   *
*   This program is free software; you can redistribute it and/or                   *
*   modify it under the terms of the GNU General Public License                     *
*   as published by the Free Software Foundation; either version 2                  *
*   of the License, or (at your option) any later version.                          *
*                                                                                   *
*   This program is distributed in the hope that it will be useful,                 *
*   but WITHOUT ANY WARRANTY; without even the implied warranty of                  *
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                   *
*   GNU General Public License for more details.                                    *
*                                                                                   *
*   You should have received a copy of the GNU General Public License               *
*   along with this program; if not, write to the Free Software                     *
*   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. *
*                                                                                   *
************************************************************************************/
#include <sstream>
#include <iomanip>
#include <memory>
#include <vector>

// FCollada
#include "FCollada.h"
#include "FCDocument\FCDocument.h"
#include "FCDocument\FCDAsset.h"
#include "FCDocument\FCDSceneNode.h"
#include "FUtils\FUUri.h"
#include "FCDocument\FCDExtra.h"

#include "MDX2.h"
#include "Buffer.h"
#include "COLLADA.h"

using namespace std;

// Output COLLADA document
FCDocument* g_doc = NULL;

int main(int argc, char* argv[])
{
    // Init FCollada
    FCollada::Initialize();

    // Load the main file buffer
    shared_ptr<Buffer> buf( new Buffer(argv[1]) );
    
    // Model header
    MDX2_FileHeader* fhead = buf->GetPointer<MDX2_FileHeader>(0);
    MDX2_Header* head = buf->GetPointer<MDX2_Header>(0x14);

    // Load additional files
    vector< shared_ptr<Buffer> > skins;
    
    string base(argv[1]);
    stringstream filename;
    
    base = base.substr(0, base.length() - 3);
    
    for(auto i = 0u; i < head->nViews; ++i)
    {
        filename << base << std::setfill('0') << std::setw(2) << i << ".skin";
        
        shared_ptr<Buffer> skin( new Buffer(filename.str().c_str()) );
        skins.push_back( skin );
        
        filename.str("");
    }

    // Create the document
    g_doc = FCollada::NewDocument();

    // The M2 file format uses Z-UP orientation
    g_doc->GetAsset()->SetUpAxis(FMVector3::ZAxis);

    // Time to work through the geometry! (Currently we only use the first skin)
    MDX2_Skin* skin = skins[0]->GetPointer<MDX2_Skin>(0);

    MDX2_Geoset* geoset = skins[0]->GetPointer<MDX2_Geoset>(skin->ofsGeosets);
    uint16_t* triangles = skins[0]->GetPointer<uint16_t>(skin->ofsTriangles);
    uint16_t* vertexLookup = skins[0]->GetPointer<uint16_t>(skin->ofsIndices);
    MDX2_Vertex* verts = buf->GetPointer<MDX2_Vertex>(head->ofsVertices);

    MDX2_Bone* bones = buf->GetPointer<MDX2_Bone>(head->ofsBones);
    uint16_t* keyBoneLookup = buf->GetPointer<uint16_t>(head->ofsKeyBoneLookup);

    for(auto i = 0U; i < skin->nGeosets; ++i)
    {
        CreateGeometry(geoset++, triangles, vertexLookup, verts);
    }

    FCDSceneNode* node = g_doc->AddVisualScene()->AddChildNode();
    node->SetDaeId("mesh-node");

    for(auto i = 0U; i < g_doc->GetGeometryLibrary()->GetEntityCount(); ++i)
    {
        FCDEntity* entity = g_doc->GetGeometryLibrary()->GetEntity(i);
        node->AddInstance(entity);
    }

    // Save the document
    if(FCollada::GetPluginManager() != NULL)
        FCollada::SaveDocument(g_doc, argv[2]);

    // Release FCollada
    FCollada::Release();
}